using DA.AnimGraph;
using System;
using System.Collections.Generic;
using UnityEngine;

namespace DA.AnimGraph.Editor {

    /**
     * Node分类：
     * NodeBase
     * - FunctionNode   除了输出节点外所有的节点
     *   - BlendNode    处于中间有多个输入端口的节点
     *   - SampleNode   提供动画数据处于末端的节点
     *   - DecorateNode 单输入单输出的修改数据用节点，暂时没有
     *   - SlotNode     比较特殊，目前没有其它同类节点，直接放在Function下面
     */
    /// <summary>
    /// 引用了资源的Node需要实现
    /// </summary>
    internal interface IResourceNode {
        /// <summary>
        /// 删除节点(或复制)时用于收集资源引用信息
        /// 如果存在多个相同资源，uuid就会有多个相同的，这是正常的
        /// </summary>
        public AUID[] GetResources();
        /// <summary>
        /// 跨文件粘贴时可能需要将原保存的id替换为当前graph中使用的id
        /// </summary>
        /// <param name="uuidMapping">旧id, 新id</param>
        public void ReplaceResourceAUID(Dictionary<AUID, AUID> uuidMapping);
    }

    internal abstract class AGANode_NodeBase {
        public Vector2 position;
        public AUID uuid;

        //public string description;
        public abstract AGANodeModelBase modelProperty { set; get; }

        public AGANode_NodeBase() {
            uuid = AUIDGenerator.Gen();
        }
    }

    internal class AGANode_Result : AGANode_NodeBase {
        [NodeInputPort("result")] public AUID result = new AUID("result");

        public override AGANodeModelBase modelProperty {
            get => throw new NotImplementedException();
            set => throw new NotImplementedException();
        }
    }


    internal abstract class AGANode_FunctionBase : AGANode_NodeBase {
        public string nodeName;
        public List<AGAPerk_PerkBase> perks;
        [NodeOutputPort("output")] public AUID output = new AUID("output");

        public AGANode_FunctionBase(AGANodeModelBase model) {
            modelProperty = model;
        }

        public abstract int Publish(List<PublishNode> outNodes, AGAPublisher.PublishContext context);

        protected void PublishPerks(PublishNode pNode, AGAPublisher.PublishContext context) {
            if (perks == null || perks.Count == 0) return;
            var tmpPerks = new List<PublishPerk>(perks.Count);
            for (int i = 0; i < perks.Count; i++) {
                var perk = perks[i].Publish(context);
                if (perk != null) {
                    tmpPerks.Add(perk);
                }
            }
            pNode.perks = tmpPerks.ToArray();
        }

    }


    internal abstract class AGANode_BlendBase : AGANode_FunctionBase {
        // todo:可以改为 AGAFieldModel_InputPort？这样NodeView中的设置也会更直接。这个修改其实不小，而且会影响已存在的配置，不要在旧项目中动
        [NodeInputPortList] public List<AUID> inputChildren = new List<AUID>();
        public List<string> inputNames = new List<string>();

        protected AGANode_BlendBase(AGANodeModelBase model) : base(model) { }
    }

    internal abstract class AGANode_SampleBase : AGANode_FunctionBase {
        protected AGANode_SampleBase(AGANodeModelBase model) : base(model) { }
    }

}
